// src/utils/request.ts
import Taro from '@tarojs/taro';
import ENV from '@/config/env';
import type { ServiceKey } from '@/config/env';
import {
  avatarUploadHeader,
  commonHeader,
  loginedTokenHeader,
  loginHeader,
  tokenHeader,
} from '@/src/utils/headers';
import { netWorkErrorInfo } from '@/src/utils/constants';

export interface RequestOptions extends Taro.request.Option<any> {
  /** 选择哪个域名，默认为 'default' */
  service?: ServiceKey;
  /** 上层传入的完整 header 对象 */
  header?: Record<string, string>;
}

// 上传文件地址
export const UPLOAD_URL = `${ENV.DOMAINS['default']}/wine-internet-community/common-api/upload`;

Taro.addInterceptor((chain) => {
  // —— 1. 拦截请求——拼域名 & 使用传入 header
  const req = chain.requestParams as RequestOptions;
  const svc = req.service || 'default';
  req.url = `${ENV.DOMAINS[svc]}${req.url}`;

  if (req.header) {
    req.header = { ...req.header };
  } else {
    delete req.header;
  }

  // —— 2. 继续请求并处理响应
  return chain
    .proceed(req)
    .then((res: any) => {
      return res;
    })
    .catch((err: any) => {
      console.warn('网络异常:', err.errMsg || err);
      // if (err.errMsg || err) {
      //   Taro.showToast({
      //     title: netWorkErrorInfo,
      //     icon: 'none',
      //   });
      //   return;
      // }
      return Promise.reject(err);
    });
});

/** 简单封装，调用处只需传入 url/data/header/service 即可 */
function apiPromise(options: RequestOptions): Promise<any> {
  console.log('接口入参：', JSON.stringify(options));
  return Taro.request(options)
    .then((r: any) => {
      // 响应日志
      console.log(
        '接口返回值：',
        options?.url,
        r?.data // 如果过大可只打印关键字段
      );
      return r.data;
    })
    .catch((e: any) => {
      // 错误日志
      console.error('接口报错信息', options?.url, e?.errMsg || e);
      throw e;
    });
}

// 公共的请求 三个入参，地址， 参数， 请求方式：POST|GET
export const commonRequestApi = async (url: string, data: any, method: any) => {
  const header = await commonHeader(url);
  return apiPromise({
    service: 'default',
    header,
    method,
    url,
    data,
  });
};

// 公共的请求 三个入参，地址， 参数， 请求方式：POST|GET
export const uploadApi = async (url: string, file: any = {}, method: any) => {
  const header = { 'Content-Type': 'application/json' };
  const data = { base64: file, type: 'storage_v5' };
  return apiPromise({
    service: 'upload',
    method,
    header,
    url,
    data,
  });
};

// 公共的请求 三个入参，地址， 参数， 请求方式：POST|GET
export const LoginRequestApi = async (
  url: string,
  data: any = {},
  method: any
) => {
  const header = await loginHeader();

  return apiPromise({
    service: 'login',
    header,
    method,
    url,
    data,
  });
};
// 公共的请求 三个入参，地址， 参数， 请求方式：POST|GET
export const avaratorRequestApi = async (
  url: string,
  data: any = {},
  method: any
) => {
  const header = await avatarUploadHeader();

  return apiPromise({
    service: 'login',
    header,
    method,
    url,
    data,
  });
};
// 公共的请求 三个入参，地址， 参数， 请求方式：POST|GET
export const LoginNewRequestApi = async (
  url: string,
  data: any = {},
  method: any
) => {
  const header = await tokenHeader();

  return apiPromise({
    service: 'login',
    header,
    method,
    url,
    data,
  });
};

// 全量信息查询，公共的请求 三个入参，地址， 参数， 请求方式：POST|GET
export const userInfoRequestApi = async (
  url: string,
  data: any = {},
  method: any
) => {
  const header = await loginedTokenHeader();

  return apiPromise({
    service: 'login',
    header,
    method,
    url,
    data,
  });
};

// 微信的服务
export const wxPostApi = async (url: string, data: any = {}) => {
  const header = { 'Content-Type': 'application/json' };
  return apiPromise({
    service: 'wxservice',
    header,
    url,
    data,
  });
};

// 上传图片或者视频到服务器地址
// 方法：POST（默认）或 "PUT"（通过 method override 覆写）
export const uploadFileApi = (
  url: string,
  filePath: string,
  name: string = 'file',
  extra: any = {},
  method: 'POST' | 'PUT' = 'POST',
  service: string = 'upload'
): Promise<string> => {
  const header = (commonHeader(url) || {}) as Record<string, string>;
  // 不要手动设置 Content-Type，multipart 的 boundary 需要底层自动生成
  if ('Content-Type' in header) delete header['Content-Type'];

  // 目标地址
  let uploadUrl = `${ENV.DOMAINS[service]}${url}`;

  // 当传入 PUT 时，采用 method override（后端需支持）
  if (method === 'PUT') {
    uploadUrl += (uploadUrl.includes('?') ? '&' : '?') + '_method=PUT';
    header['X-HTTP-Method-Override'] = 'PUT';
  }

  // formData 建议保证为字符串
  const formData: Record<string, string> = {};
  Object.keys(extra || {}).forEach((k) => (formData[k] = String(extra[k])));
  console.log(uploadUrl, filePath, name, formData, header, '========');
  return new Promise<string>((resolve, reject) => {
    Taro.uploadFile({
      url: uploadUrl,
      name,
      filePath,
      formData,
      header,
      success: (res: any) => {
        if (res.statusCode && res.statusCode >= 400) {
          reject(new Error(`HTTP ${res.statusCode}`));
          return;
        }
        let data: any;
        try {
          data = typeof res.data === 'string' ? JSON.parse(res.data) : res.data;
        } catch {
          reject(new Error('上传响应解析失败'));
          return;
        }
        const fileUrl =
          data?.data?.fileUrl || data?.fileUrl || data?.data?.url || data?.url;
        if (fileUrl) {
          resolve(fileUrl);
          return;
        }
        const msg = data?.message || data?.msg || '上传失败（未返回文件地址）';
        const code = data?.code ?? data?.success;
        reject(
          new Error(`${msg}${code !== undefined ? `, code=${code}` : ''}`)
        );
      },
      fail: (err) => reject(err),
    });
  });
};
